home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
tools
/
sharp
/
xc2103i.lzh
/
XC2103.XDF
/
ASK30
/
KANJISEL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-15
|
7KB
|
363 lines
/*
** 部首名検索 for ASK3
** Copyright (C) 1992 ACCESS CO.,LTD.
*/
#include "aci.h"
#include "askkey.h"
typedef unsigned char u_char;
short acc_main();
u_char cbuf[80];
MEAN kbuf[81];
MEAN mbuf[9];
ACC_DEF acc = {
KS_EDIT0|KS_EDITING,
CTRL_ON|NOT_ASCII|CODE_IN,
acc_main,
{
cbuf, kbuf, mbuf
}
};
#define BUFSIZE 1024
static u_char line[BUFSIZE]; /* 読み込みバッファ */
static u_char *linep; /* 文字へのポインタ*/
static u_char dicname[64]; /* 辞書ファイル */
static int fd;
short acc_main(code)
BIT16 code;
{
BIT16 nc, mask_key();
u_char *strcpy();
void next_moji(), next_bushu(), next_kakusu(), enter();
static u_char askinput[80]; /* 仮入力文字列 */
static int first = 1;
static int second = 0;
static int urgent = 0;
/* CACI_URGENT はメッセージを表示するために */
/* 一瞬ASKに処理を戻すために使っている */
if (first) {
first = 0;
second = 1;
strcpy(askinput, cbuf);
sstrtom("部首検索", mbuf, 0);
sstrtom("辞書オープン中です...", kbuf, 0);
return(DF_MWINSTR|DF_KWINSTR|CACI_URGENT);
} else if (second) {
second = 0;
if (init(dicname, askinput) < 0) {
urgent = 1;
xclose(fd);
sstrtom("部首検索辞書が不正です", kbuf, 0);
return(DF_KWINSTR|CACI_URGENT);
}
return(DF_KWINSTR|CACI_NORMAL);
} else if (urgent) {
for (urgent = 10000; urgent > 0; urgent--) {
first = 200 * 30.0 / 12.0;
}
urgent = 0;
first = 1;
xclose(fd);
return(CACI_END);
}
nc = mask_key(code);
switch(nc) {
case NOT_ASCII|LEFT_KEY:
next_moji(-1);
break;
case NOT_ASCII|RIGHT_KEY:
next_moji(1);
break;
case NOT_ASCII|UP_KEY:
next_bushu(-1);
break;
case NOT_ASCII|DOWN_KEY:
next_bushu(1);
break;
case CTRL_ON|NOT_ASCII|UP_KEY:
next_kakusu(-1);
break;
case CTRL_ON|NOT_ASCII|DOWN_KEY:
next_kakusu(1);
break;
case '\r':
enter();
return(DF_OUTSTR|CACI_SUSPEND);
case CTRL_ON|NOT_ASCII|CODE_IN:
case CTRL_ON|NOT_ASCII|CODE_OUT:
case '\033':
first = 1;
xclose(fd);
return(CACI_END);
case CTRL_ON|NOT_ASCII|XF1_KEY:
first = 1;
xclose(fd);
return(KEY_AGAIN|CACI_END);
default:
break;
}
return(DF_KWINSTR|CACI_NORMAL);
}
static BIT16 mask_key(code)
BIT16 code;
{
code &= (0xff|CTRL_ON|SHIFT_ON|NOT_ASCII);
if (!(code & NOT_ASCII))
code &= ~CTRL_ON;
return(code);
}
#define TBLSIZE 256 /* 辞書のインデックス */
static struct {
short kakusu; /* 画数 */
u_char bushuname[32]; /* 部首名 */
long offset; /* オフセット */
} block[TBLSIZE];
static int cur_block; /* 現在の表示ブロック */
static int cur_moji; /* 選択されている文字 */
static int totalblocks; /* 総ブロック数 */
static int init(fname, askinput)
u_char *fname, *askinput;
{
int i, j;
u_char *p, *ltos();
long lastoffset = 0;
cur_block = cur_moji = totalblocks = -1;
if ((fd = xopen(fname, 0x0000)) < 0)
return(fd = -1);
/* 辞書をスキャンしてオンメモリでインデックスを作る。 */
/* 辞書は1行1レコードで、 */
/* 画数,部首名,漢字並び */
/* を1レコードとする。漢字は必ず2バイト文字。 */
for (i = 0; getline(fd, line, BUFSIZE) > 0 && i < TBLSIZE; i++) {
block[i].offset = lastoffset;
lastoffset = xseek(fd, 0, 1);
block[i].kakusu = 0;
for (p = line; *p != ','; p++) {
if (*p >= '0' && *p <= '9') {
block[i].kakusu *= 10;
block[i].kakusu += (*p - '0');
} else {
return(-1);
}
}
if ((i > 0) && (block[i-1].kakusu > block[i].kakusu)) {
return(-1); /* 画数が昇順になっていない */
}
for (j = 0, ++p; *p != ','; p += 2) {
if (*p == (u_char)0) {
return(-1);
} else {
block[i].bushuname[j++] = *p;
block[i].bushuname[j++] = *(p+1);
}
}
block[i].bushuname[j] = (u_char)0;
}
if ((totalblocks = i) == 0) {
return(-1);
}
if (*askinput != (u_char)0) {
for (i = 0; i < totalblocks; i++) {
if (strcmp(block[i].bushuname, askinput) == 0) {
cur_block = i - 1;
break;
}
}
}
next_bushu(1);
return(0);
}
/* 表示関係。64文字モードには未対応 */
#define KWINLEN 80 /* 候補ウィンドウの長さ */
#define NKOUHO 16 /* 1行の最大文字数 */
static void next_moji(sign)
int sign;
{
u_char *p, *makedisp();
if (sign < 0) { /* 前の文字 */
if (cur_moji > 0)
--cur_moji;
else
return;
} else { /* 次の文字 */
if (*(linep + cur_moji * 2 + 2) != (u_char)0)
++cur_moji;
else
return;
}
p = makedisp(linep + (cur_moji / NKOUHO) * NKOUHO * 2,
block[cur_block].bushuname);
sstrtom(p, kbuf, 0);
chgkind(&kbuf[(cur_moji % NKOUHO * 4) + 2], 2, 1);
}
static void next_bushu(sign)
int sign;
{
u_char *p, *makedisp();
if (sign < 0) { /* 前の部首 */
if (cur_block > 0)
--cur_block;
else
return;
} else { /* 次の部首 */
if (cur_block < totalblocks-1)
++cur_block;
else
return;
}
if (xseek(fd, block[cur_block].offset, 0) < 0)
return;
if (getline(fd, line, BUFSIZE) <= 0)
return;
linep = line;
while (*linep++ != ',') ;
while (*linep != ',') linep += 2;
p = makedisp(++linep, block[cur_block].bushuname);
sstrtom(p, kbuf, 0);
chgkind(&kbuf[2], 2, 1);
cur_moji = 0;
}
static void next_kakusu(sign)
int sign;
{
int i;
if (sign < 0) { /* ひとつ少ない画数 */
for (i = cur_block - 1; i >= 0; i--) {
if (block[i].kakusu < block[cur_block].kakusu)
break;
}
} else { /* ひとつ多い画数 */
for (i = cur_block + 1; i < totalblocks; i++) {
if (block[i].kakusu > block[cur_block].kakusu)
break;
}
}
if (i >= 0 && i < totalblocks) {
cur_block = i - 1;
next_bushu(1);
}
}
static void enter()
{
cbuf[0] = *(linep + cur_moji * 2);
cbuf[1] = *(linep + cur_moji * 2 + 1);
cbuf[2] = (u_char)0;
}
static u_char *makedisp(kanji_str, bushuname)
u_char *kanji_str, *bushuname;
{
static u_char disp_line[100];
int i, sp;
u_char *p = disp_line;
for (i = 0; i < NKOUHO; i++, p += 4) {
if (*kanji_str == (u_char)0) {
break;
} else {
*p = *(p + 1) = ' ';
*(p + 2) = *kanji_str++;
*(p + 3) = *kanji_str++;
}
}
*p = (u_char)0;
i = strlen(disp_line) + strlen(bushuname);
sp = (i + 2 <= KWINLEN) ? (KWINLEN - i) : 2;
while (sp--)
*p++ = ' ';
strcpy(p, bushuname);
*(disp_line + KWINLEN) = (u_char)0;
return(disp_line);
}
static int getline(fd, buf, bufsize)
int fd;
char *buf;
int bufsize;
{
u_char inbuf[2+255+1];
int total, len, i;
total = 0;
inbuf[0] = 255;
while ((len = fgets(fd, inbuf)) > 0) {
for (i = 2; i < len + 2; i++) {
if (inbuf[i] == 0x1a) {
inbuf[i] = '\0';
len = i - 2;
break;
}
}
if ((total + len) >= bufsize) {
return(0);
}
strcpy(&buf[total], &inbuf[2]);
total += len;
if (len < 255) {
return(total);
}
}
return(0); /* EOF */
}
static u_char *strcpy(s1, s2)
u_char *s1, *s2;
{
u_char *ret = s1;
while (*s1++ = *s2++)
;
return(ret);
}
static int strlen(s)
u_char *s;
{
u_char *p = s;
while (*s)
s++;
return(s - p);
}
static int strcmp(s1, s2)
u_char *s1, *s2;
{
while (*s1 && *s2 && *s1 == *s2) {
s1++;
s2++;
}
return(*s1 - *s2);
}
int scanarg(arg)
u_char *arg;
{
while (*arg++ != 0)
;
if (*arg == 0)
return(1);
else if (*arg == '/' && (*(arg+1) == 'D' || *(arg+1) == 'd')) {
strcpy(dicname, arg+2);
return(0);
} else
return(1);
}